package com.wang.project.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.project.common.ErrorCode;
import com.wang.project.constant.MQConstant;
import com.wang.project.constant.PaymentEnum;
import com.wang.project.exception.BusinessException;
import com.wang.project.mapper.InterfaceInfoMapper;
import com.wang.project.mapper.UserInterfacePaymentMapper;
import com.wang.project.model.dto.InterfacePay.InterfaceAddNumRequest;
import com.wang.project.model.dto.InterfacePay.OrderInterfaceQueryRequest;
import com.wang.project.model.entity.InterfaceInfo;
import com.wang.project.model.entity.User;
import com.wang.project.model.entity.UserInterfacePayment;
import com.wang.project.model.modle.MQInerfacePaymentModel;
import com.wang.project.model.modle.PayModel;
import com.wang.project.model.vo.pay.OrderInterfaceAddNumVO;
import com.wang.project.pay.PayContext;
import com.wang.project.pay.PayStrategyByZFB;
import com.wang.project.pay.PayStrategyModel;
import com.wang.project.pay.zfb.AlipayFaceToFaceService;
import com.wang.project.pay.zfb.ZFBPreorderActionVO;
import com.wang.project.service.UserInterfacePaymentService;
import com.wang.project.service.UserService;
import com.wang.project.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 胡歌的腿毛
 * @description 针对表【user_interface_payment】的数据库操作Service实现
 * @createDate 2023-09-22 17:58:25
 */
@Service
@Slf4j
public class UserInterfacePaymentServiceImpl extends ServiceImpl<UserInterfacePaymentMapper, UserInterfacePayment>
        implements UserInterfacePaymentService {

    @Resource
    private UserService userService;

    @Resource
    private InterfaceInfoMapper interfaceInfoMapper;

    @Resource
    private AlipayFaceToFaceService alipayFaceToFaceService;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    private final static Map<String, Double> payAmountMap = new HashMap<>();
    private final static Map<String, String> payOrderNumberPreFixMap = new HashMap<>();


    static {
        payAmountMap.put("addInterfaceNum", 8.8);

        payOrderNumberPreFixMap.put("addInterfaceNum", "AN"); //增加接口调用次数的订单号前缀
    }

    //private final static String sourceScene = "支付宝"; //支付场景  后面添加微信支付场景


    /**
     * 增加接口调用次数支付处理逻辑
     *
     * @param interfaceAddNumRequest 要支付的接口id集合 支付来源
     * @param request
     * @param response
     * @return
     */
    @Override
    public ZFBPreorderActionVO addInterfaceNum(InterfaceAddNumRequest interfaceAddNumRequest, HttpServletRequest request, HttpServletResponse response) {
        final String subject = "增加接口调用次数50次";
        //校验参数
        List<Long> interfaceIdList = interfaceAddNumRequest.getIdList();
        if (CollUtil.isEmpty(interfaceIdList)) {
            log.info("PaymentServiceImpl addInterfaceNum idList为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数不能为空，请重试");
        }
        List<InterfaceInfo> interfaceInfos = interfaceInfoMapper.selectBatchIds(interfaceIdList);
        if (CollUtil.isEmpty(interfaceInfos)) {
            log.info("PaymentServiceImpl addInterfaceNum interfaceInfos为空");
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "数据不存在");
        }

        //组装参数
        PayModel payModel = new PayModel();
        User loginUser = userService.getLoginUser(request);
        payModel.setUser(loginUser);
        payModel.setAmount(payAmountMap.get("addInterfaceNum"));
        payModel.setPayCount(interfaceInfos.size());
        payModel.setSubject(subject);
        String sourceScene = interfaceAddNumRequest.getSourceScene();
        payModel.setSourceScene(sourceScene);
        String alipayOutTradeNo = CommonUtils.getAlipayOutTradeNo(payOrderNumberPreFixMap.get("addInterfaceNum"));
        payModel.setOrderNumber(alipayOutTradeNo);

        //处理支付逻辑 策略模式
        PayStrategyModel payStrategyModel = new PayContext(new PayStrategyByZFB()).algorithmInterface(request, response, payModel);
        ZFBPreorderActionVO zfbPreorderActionVO = new ZFBPreorderActionVO();
        BeanUtils.copyProperties(payStrategyModel, zfbPreorderActionVO);

        //发送mq消息
        MQInerfacePaymentModel mqInerfacePaymentModel = new MQInerfacePaymentModel();
        mqInerfacePaymentModel.setUserId(loginUser.getId());
        mqInerfacePaymentModel.setInterfaceIdList(interfaceIdList);
        mqInerfacePaymentModel.setAmount(BigDecimal.valueOf(payAmountMap.get("addInterfaceNum")));
        mqInerfacePaymentModel.setOrderId(alipayOutTradeNo);
        mqInerfacePaymentModel.setPayStatus(PaymentEnum.UnPay.getCode());
        mqInerfacePaymentModel.setSourceScene(sourceScene);

        rocketMQTemplate.asyncSend(MQConstant.TOPIC_PAYMENT_ADDINTERFACENUM, mqInerfacePaymentModel, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("发送消息成功");
            }

            // todo 当消息失败后，将消息放入死信队列 等待后续消息补偿
            @Override
            public void onException(Throwable throwable) {
                log.info("发送消息失败,等待补偿操作");
            }
        });

        //返回VO
        zfbPreorderActionVO.setSubject(subject);
        zfbPreorderActionVO.setAmount(payAmountMap.get("addInterfaceNum"));
        return zfbPreorderActionVO;
    }


    /**
     * 获取order list
     *
     * @param orderInterfaceQueryRequest
     * @param request
     * @return
     */
    @Override
    public List<OrderInterfaceAddNumVO> getPaymentListQuery(OrderInterfaceQueryRequest orderInterfaceQueryRequest, HttpServletRequest request) {
        if (orderInterfaceQueryRequest == null) {
            log.info("PaymentServiceImpl getPaymentListQuery orderRefreshKeyQueryRequest is null");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserInterfacePayment userInterfacePayment = new UserInterfacePayment();
        BeanUtils.copyProperties(orderInterfaceQueryRequest, userInterfacePayment);
        QueryWrapper<UserInterfacePayment> queryWrapper = new QueryWrapper<>(userInterfacePayment);
        List<UserInterfacePayment> userInterfacePayments = this.list(queryWrapper);
        List<OrderInterfaceAddNumVO> orderInterfaceAddNumVOList = userInterfacePayments.stream().map(item -> {
            OrderInterfaceAddNumVO orderInterfaceAddNumVO = new OrderInterfaceAddNumVO();
            BeanUtils.copyProperties(item, orderInterfaceAddNumVO);
            return orderInterfaceAddNumVO;
        }).collect(Collectors.toList());
        return orderInterfaceAddNumVOList;

    }

    /**
     * 分页查询
     *
     * @param orderInterfaceQueryRequest
     * @param request
     * @return
     */
    @Override
    public Page<OrderInterfaceAddNumVO> listUserByPage(OrderInterfaceQueryRequest orderInterfaceQueryRequest, HttpServletRequest request) {

        long size = 10;
        long current = 1;
        UserInterfacePayment userInterfacePayment = new UserInterfacePayment();
        if (orderInterfaceQueryRequest != null) {
            BeanUtils.copyProperties(orderInterfaceQueryRequest, userInterfacePayment);
            current = orderInterfaceQueryRequest.getCurrent();
            size = orderInterfaceQueryRequest.getPageSize();
        }
        QueryWrapper<UserInterfacePayment> queryWrapper = new QueryWrapper<>(userInterfacePayment);
        Page<UserInterfacePayment> userInterfacePaymentPage = this.page(new Page<>(current, size), queryWrapper);
        Page<OrderInterfaceAddNumVO> orderInterfaceAddNumVOPage = new PageDTO<>(userInterfacePaymentPage.getCurrent(), userInterfacePaymentPage.getSize(), userInterfacePaymentPage.getTotal());
        List<OrderInterfaceAddNumVO> orderInterfaceAddNumVOList = orderInterfaceAddNumVOPage.getRecords().stream().map(item -> {
            OrderInterfaceAddNumVO orderInterfaceAddNumVO = new OrderInterfaceAddNumVO();
            BeanUtils.copyProperties(item, orderInterfaceAddNumVO);
            return orderInterfaceAddNumVO;
        }).collect(Collectors.toList());
        orderInterfaceAddNumVOPage.setRecords(orderInterfaceAddNumVOList);
        return orderInterfaceAddNumVOPage;
    }
}




